/** * License Agreement. * * Rich Faces - Natural Ajax for Java Server Faces (JSF) * * Copyright (C) 2007 Exadel, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.richfaces.builder.mojo; import java.io.File; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.DirectoryScanner; /** * @author shura * */ public abstract class AbstractCDKMojo extends AbstractMojo { /** * Project classpath. */ @Parameter(property="project.compileClasspathElements", readonly=true, required=true) protected List classpathElements; /** * The source directories containing the sources to be compiled. */ @Parameter(property="project.compileSourceRoots", required=true, readonly=true) protected List<String> compileSourceRoots; /** * Place for component configuration XML files. All '*.xml' files wil be parsed as components config. All '*.ent' files will * be processed as include configurations. */ @Parameter(defaultValue="src/main/config/component") protected File componentConfigDirectory; /** * Place for converter configuration XML files. All '*.xml' files wil be parsed as components config. All '*.ent' files will * be processed as include configurations. */ @Parameter(defaultValue="src/main/config/converter") protected File converterConfigDirectory; /** * Place for faces configuration XML files * * */ @Parameter( defaultValue="src/main/config/faces") protected File facesConfigInclude; @Parameter protected String key; @Parameter protected Library library; /** * The directory for compiled classes. */ @Parameter(property="project.build.outputDirectory", required=true, readonly=true) protected File outputDirectory; /** * Directory where the output Java Files will be located. */ @Parameter(defaultValue="${project.build.directory}/generated-component/java") protected File outputJavaDirectory; /** * Directory where the output Java Files will be located. */ @Parameter( defaultValue="${project.build.directory}/generated-component/resources") protected File outputResourcesDirectory; @Parameter(defaultValue="${project.build.directory}/generated-component/test") protected File outputTestsDirectory; /** * Top maven project. */ @Parameter(property="project", readonly=true) protected MavenProject project; /** * Place for component configuration XML files */ @Parameter(defaultValue="src/main/config/resources") protected File resourcesInclude; /** * Place for component configuration XML files */ @Parameter(defaultValue="src/main/config/taglib") protected File taglibInclude; @Parameter(defaultValue="src/main/templates") protected File templatesDirectory; /** * Place for validator configuration XML files. All '*.xml' files wil be parsed as component config. All '*.ent' files will * be processed as include configurations. */ @Parameter(defaultValue="src/main/config/validator") protected File validatorConfigDirectory; /** * Check library configuration, and fill all empty values to default. * * @return */ protected Taglib checkLibraryConfig() { if (null != library) { getLog().debug("Library prefix is " + library.getPrefix()); } else { library = new Library(); } if (null == library.getPrefix()) { library.setPrefix(project.getGroupId()); } getLog().debug("Default prefix for a generated packages: " + library.getPrefix()); if (null == library.getDescription()) { library.setDescription(project.getDescription()); } getLog().debug("Library description: " + library.getDescription()); if (null == library.getJsfVersion()) { String version = Library.JSF11; // Check version-specific methods in UIComponent class try { Class<?> componentClass = createProjectClassLoader(project, false).loadClass( "javax.faces.component.UIComponent"); Method[] methods = componentClass.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { if ("encodeAll".equals(methods[i].getName())) { version = Library.JSF12; break; } } } catch (ClassNotFoundException e) { // Ignore - by defaule, generate codes for JSF 1.1 } library.setJsfVersion(version); } // velocity = new DefaultVelocityComponent(); getLog().debug("Generate files for a JSF " + library.getJsfVersion()); Renderkit[] renderkits = library.getRenderkits(); if (null != renderkits) { for (int i = 0; i < renderkits.length; i++) { Renderkit renderkit = renderkits[i]; getLog().debug("Renderkit name is " + renderkit.getName()); if (null == renderkit.getPackage()) { renderkit.setPackage(library.getPrefix() + ".renderkit." + renderkit.getName().toLowerCase()); } } } else { renderkits = new Renderkit[1]; Renderkit renderkit = new Renderkit(); renderkit.setMarkup("html"); renderkit.setName("HTML_BASIC"); renderkit.setPackage(library.getPrefix() + ".renderkit." + renderkit.getName().toLowerCase()); renderkits[0] = renderkit; library.setRenderkits(renderkits); } Taglib taglib = library.getTaglib(); if (null != taglib) { getLog().debug("Taglib uri is " + taglib.getUri()); getLog().debug("Taglib shortname is " + taglib.getShortName()); } else { taglib = new Taglib(); library.setTaglib(taglib); } if (null == taglib.getDisplayName()) { taglib.setDisplayName(project.getDescription()); } if (null == taglib.getJspVersion()) { // Jsf 1.2 can use JSP 2.1 only, other - 2.0 taglib.setJspVersion(library.getJsfVersion().equals(Library.JSF12) ? "2.1" : "1.2"); } if (null == taglib.getUri()) { String url = project.getUrl(); if (null == url) { url = "http://"; String[] parts = project.getGroupId().split("."); for (int i = parts.length - 1; i >= 0; i--) { url = url + parts[i]; if (i > 0) { url = url + "."; } } url = url + "/" + project.getArtifactId(); } taglib.setUri(url); } if (null == taglib.getShortName()) { taglib.setShortName(project.getArtifactId()); } if (null == taglib.getTaglib()) { taglib.setTaglib(taglib.getShortName()); } if (null == taglib.getTlibVersion()) { taglib.setTlibVersion(createTaglibVersionFromProjectVersion()); } getLog().debug("Taglib uri is " + taglib.getUri()); getLog().debug("Taglib shortname is " + taglib.getShortName()); if (null != library.getTaglibs() && library.getTaglibs().length > 0) { for (int i = 0; i < library.getTaglibs().length; i++) { Taglib t = library.getTaglibs()[i]; checkTaglib(t); } } return taglib; } private String createTaglibVersionFromProjectVersion() { Artifact artifact = project.getArtifact(); String version = artifact.getVersion(); Matcher matcher = Pattern.compile("^(\\d+(?:\\.\\d+)*)").matcher(version); if (matcher.find()) { return matcher.group(1); } return "1.2"; } protected ClassLoader createProjectClassLoader(MavenProject project, boolean useCCL) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { List<?> compileClasspathElements = project.getCompileClasspathElements(); String outputDirectory = project.getBuild().getOutputDirectory(); URL[] urls = new URL[compileClasspathElements.size() + 1]; int i = 0; urls[i++] = new File(outputDirectory).toURI().toURL(); for (Iterator<?> iter = compileClasspathElements.iterator(); iter.hasNext();) { String element = (String) iter.next(); urls[i++] = new File(element).toURI().toURL(); } if (useCCL) { classLoader = new URLClassLoader(urls, classLoader); } else { classLoader = new URLClassLoader(urls); } } catch (MalformedURLException e) { getLog().error("Bad URL in classpath", e); } catch (DependencyResolutionRequiredException e) { getLog().error("Dependencies not resolved ", e); } return classLoader; } protected ClassLoader createProjectClassLoader(MavenProject project) { return createProjectClassLoader(project, true); } protected void checkTaglib(Taglib taglib) { if (null == taglib.getDisplayName()) { taglib.setDisplayName(library.getTaglib().getDisplayName()); } if (null == taglib.getShortName()) { taglib.setShortName(library.getTaglib().getShortName()); } if (null == taglib.getJspVersion()) { taglib.setJspVersion(library.getTaglib().getJspVersion()); } if (null == taglib.getUri()) { taglib.setUri(library.getTaglib().getUri() + "/" + taglib.getShortName()); } if (null == taglib.getTaglib()) { taglib.setTaglib(taglib.getShortName()); } if (null == taglib.getTlibVersion()) { taglib.setTlibVersion(createTaglibVersionFromProjectVersion()); } getLog().debug("Taglib uri is " + taglib.getUri()); getLog().debug("Taglib shortname is " + taglib.getShortName()); getLog().debug("Taglib version is " + taglib.getTlibVersion()); } protected String[] doScan(String[] includes, String[] excludes, File rootFolder) throws MojoExecutionException { try { DirectoryScanner directoryScanner = new DirectoryScanner(); directoryScanner.setFollowSymlinks(true); directoryScanner.setBasedir(rootFolder); directoryScanner.setExcludes(excludes); directoryScanner.setIncludes(includes); directoryScanner.addDefaultExcludes(); directoryScanner.scan(); return directoryScanner.getIncludedFiles(); } catch (IllegalStateException e) { throw new MojoExecutionException("Error scanning source root: \'" + rootFolder + "\'", e); } } }